package com.lifeng.beanannotation;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.MethodIntrospector;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Map;

/**
 * @author lifeng
 * @version v1.0
 * @date 2020/11/10 17:40
 * @description 获取带有某个注解的方法
 */
@Component
public class UserInit implements ApplicationContextAware, InitializingBean {
    public static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
		//获取所有的bean
        String[] beanDefinitionNames = applicationContext.getBeanNamesForType(Object.class, false, true);
        for (String beanDefinitionName : beanDefinitionNames) {
            Object bean = applicationContext.getBean(beanDefinitionName);
            Map<Method, MethodAnnotation> annotatedMethods = null;
			//获取bean下所有带有某个注解的方法
            annotatedMethods = MethodIntrospector.selectMethods(bean.getClass(),
                    new MethodIntrospector.MetadataLookup<MethodAnnotation>() {
                        @Override
                        public MethodAnnotation inspect(Method method) {
                            return AnnotatedElementUtils.findMergedAnnotation(method, MethodAnnotation.class);
                        }
                    });
            if(annotatedMethods!=null&& annotatedMethods.size()>0){
                System.out.println("bean:"+bean.getClass().getName()+",method:"+annotatedMethods);
            }
        }
		//获取带有某个注解的类
        String[] withAnnotataionClassName = applicationContext.getBeanNamesForAnnotation(ClassAnnotation.class);
        System.out.println(withAnnotataionClassName);
        for(String className:withAnnotataionClassName) {
        	Object bean = applicationContext.getBean(className);
        	System.out.println(bean);
        }
        //通过beanName获取某个类上的注解
        ClassAnnotation clazzAnno = applicationContext.findAnnotationOnBean("userService", ClassAnnotation.class);
        System.out.println(clazzAnno);
        
        //获取所有带有某个注解的类
        Map<String,Object> clazzs = applicationContext.getBeansWithAnnotation(ClassAnnotation.class);
        System.out.println(clazzs);
    }
}
